package diskScheduling;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;

/**
 * 磁盘调度
 * 58 18 160 38 55 39 90 150 184 0
 */
public class DiskScheduling_xhh {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("输入磁盘调度的序列，并以0结束");
        List<Integer> list = new ArrayList<>();
        while (scanner.hasNextInt()) {
            int location = scanner.nextInt();
            if (location == 0) {
                break;
            }
            list.add(location);
        }

        System.out.println("请输入从第几号扇区开始调度？");
        int begin = scanner.nextInt();
        
        System.out.println("请选择调度方式：");
        System.out.println("1、先来先服务FCFS");
        System.out.println("2、最短寻道时间优先SSTF");
        System.out.println("3、电梯调度算法SCAN");
        System.out.println("其他，退出");
        System.out.print("请输入调度方式对应的序号:");
        
        boolean flag = true;
        while (flag) {
            int select = scanner.nextInt();
            switch (select) {
                case 1:
                    System.out.println("你选择了先来先服务FCFS，扫描顺序如下：");
                    fcfs(list, begin);
                    break;
                case 2:
                    System.out.println("你选择了最短寻道时间优先SSTF，扫描顺序如下：");
                    sstf(new ArrayList<>(list), begin);
                    break;
                case 3:
                    System.out.println("你选择了电梯调度算法SCAN，扫描顺序如下：");
                    System.out.println("磁盘移动的方向：1、由内向外 || 2、由外向内  ");
                    boolean direction = "2".equals(scanner.next());
                    scan(list, begin, direction);
                    break;
                default:
                    flag = false;
                    break;
            }
        }
    }

    /**
     * 先来先服务算法
     * @param list 调度序列
     * @param begin 起始扇区
     */
    public static void fcfs(List<Integer> list, int begin) {
        double length = 0;
        for (Integer integer : list) {
            System.out.print(integer + " ");
            length += Math.abs(begin - integer);
            begin = integer;
        }
        System.out.println();
        System.out.println("平均寻道长度为 ：" + (length/list.size()));
    }

    public static void sstf(List<Integer> list, int begin) {
        int i = 0;
        double length = 0;
        int[] path = new int[list.size()];
        while (i < list.size()) {
            int index = 0, min = Math.abs(begin - list.get(0));
            for (int j = 1; j < list.size(); j++) {
                if (Math.abs(begin - list.get(j)) < min) {
                    index = j;
                    min = Math.abs(begin - list.get(j));
                }
            }
            path[i] = new Integer(list.get(index));
            length += min;
            begin = list.get(index);
            list.set(index, Integer.MAX_VALUE);
            i++;
        }

        for (Integer integer : path) {
            System.out.print(integer + " ");
        }
        System.out.println();
        System.out.println("平均寻道长度为 ：" + (length/list.size()));
    }

    /**
     *
     * @param list
     * @param begin
     * @param direction 规定为true是由外向内
     */
    public static void scan(List<Integer> list, int begin, boolean direction) {
        Collections.sort(list);
        int[] path = new int[list.size()];
        int num = 0;
        double length = 0;
        if (direction) {
            for (int i = 0; i < list.size(); i++) {
                if (list.get(i) >= begin) {
                    path[num++] = list.get(i);
                    length += Math.abs(list.get(i) - begin);
                    begin = list.get(i);
                }
            }
            int rest = list.size() - num - 1;
            while (rest >= 0) {
                path[num++] = list.get(rest);
                length += Math.abs(list.get(rest) - begin);
                begin = list.get(rest);
                rest--;
            }
        } else {
            for (int i = list.size() - 1; i >= 0; i--) {
                if (list.get(i) <= begin) {
                    path[num++] = list.get(i);
                    length += Math.abs(list.get(i) - begin);
                    begin = list.get(i);
                }
            }
            int rest = num;
            while (rest < list.size()) {
                path[num++] = list.get(rest);
                length += Math.abs(list.get(rest) - begin);
                begin = list.get(rest);
                rest++;
            }
        }
        for (Integer integer : path) {
            System.out.print(integer + " ");
        }
        System.out.println();
        System.out.println("平均寻道长度为 ：" + (length/list.size()));
    }
}
